/**基础数据处理 */
import MBase from "../utils/m-base";
/**文件目录处理 */
import MFile from "../utils/m-file";
/**配置文件处理 */
import MConfig from "../utils/m-config";
/**类型定义 */
import { IGlobal } from "../m-types";

/**命令处理 */
export default class MCmder {
  /**解析参数列表 */
  public static decodeArgs(args: string | Array<string>) {
    const argNames: Record<string, Array<string>> = {
      addr: "-a,addr".split(","), //请求地址
      dir: "-d,dir".split(","), //生成目录
      name: "-n,name".split(","), //项目名称
      user: "-u,user".split(","), //授权用户名
      offline: "-o,offline".split(","), //使用线下文件
      pass: "-p,pass".split(","), //授权密码
      writer: "-w,writer".split(","), //书写器名称
    };
    const parms = args instanceof Array ? args : args.split(/\s+/);
    const result: Record<string, string> = {};
    for (const p in parms) {
      if (typeof parms[p] != "string") continue;
      if (!parms[p].includes("=")) continue;
      const [key, val] = parms[p].split("=").map((x) => MBase.trimStr(x));
      for (let n in argNames) {
        if (argNames[n].includes(key)) result[n] = val || "";
      }
    }
    return result;
  }
  /**逆向解析参数 */
  public static encodeArgs(parm: IGlobal) {
    const { cmdName, apiName, dir, addr, offline } = parm;
    const { authUser, authPass, writerName } = parm;
    const res: Record<string, string> = {};
    let cmd = `npm run ${cmdName}`;
    res["-a"] = addr;
    res["-d"] = dir;
    res["-n"] = apiName;
    res["-u"] = authUser;
    res["-p"] = authPass;
    res["-o"] = offline ? "true" : "";
    res["-w"] = writerName;
    cmd = `${cmd} -n=${apiName}`;
    cmd = `${cmd} -d=${dir}`;
    cmd = `${cmd} -w=${writerName}`;
    if (offline) cmd = `${cmd} -o=true`;
    if (authUser) cmd = `${cmd} -u=${authUser} -p=${authPass}`;
    cmd = `${cmd} -a=${addr}`;
    res["cmd"] = cmd;
    return res;
  }
  /**获取命令信息 */
  public static async getParm(): Promise<IGlobal> {
    const infos = process.argv || [];
    const res = {} as IGlobal;
    const [service, script, ...args] = infos;
    const other = MCmder.decodeArgs(args);
    const { addr, dir, name, user, pass, offline, writer } = other;
    const config = await MConfig.load();
    const cmdPath = MFile.getRoot();
    const cmdName = config.getName() || "";
    const url = addr || "";
    const dirPath = dir || "./src/api";
    const apiName = name || "test";
    const workPath = MBase.trimStr(cmdPath.split(/[/\\]node_modules[/\\]/i)[0]);
    const isOffline = (offline || "false").toLowerCase() == "true";

    res.service = service;
    res.script = script;
    res.addr = url;
    res.dir = dirPath;
    res.authUser = user || "";
    res.authPass = pass || "";
    res.offline = isOffline;
    res.cmdName = cmdName;
    res.cmdPath = cmdPath;
    res.workPath = workPath;
    res.apiName = apiName;
    res.writerName = writer || "ts+axios";
    res.apiPath = MFile.joinDirPath(workPath, dirPath, apiName);
    res.swgFile = isOffline ? MCmder.getClientUrl(res, url || "./") : "";
    res.swgUrl = isOffline ? "" : MCmder.getServerUrl(url);
    res.swgJson = { info: { title: "", version: "" } };
    res.result = { methods: [], models: [], enums: [] };
    return res;
  }

  /**获取本地配置文件地址 */
  private static getClientUrl(parm: IGlobal, path: string) {
    const paths = [parm.workPath, path];
    if (!path.endsWith(".json")) paths.push("swagger.json");
    return MFile.joinDirPath(...paths);
  }
  /**获取远程配置文件地址 */
  private static getServerUrl(host: string) {
    const isUrl = /^https?:\/\//i.test(host) || false;
    const url = isUrl ? host : `http://${host}`;
    const urls = [url];
    if (!host) return "";
    if (!url.endsWith(".json")) urls.push("swagger.json");
    return MFile.joinUrlPath(...urls);
  }
}
